
import numpy as np
import pandas as pd
from datetime import datetime, timedelta
from typing import List, Dict, Any
from collections import defaultdict

def get_activity_duration(activity, event_log):
    """计算活动平均持续时间（基于历史事件日志）"""
    # 从事件日志中获取该活动的所有持续时间记录
    durations = []
    for case in event_log:
        activities = case[case['activity'] == activity]
        if len(activities) > 1:
            start = activities.iloc[0]['timestamp']
            end = activities.iloc[-1]['timestamp']
            durations.append((end - start).total_seconds())
    
    # 返回平均持续时间（秒），至少有1小时默认值
    return np.mean(durations) if durations else 3600


def is_goal_activity(activity, case_events=None):
    """带案例上下文的增强版判断"""
    # 基础检查
    if activity in {'审批通过', '流程结束'}:
        return True
        
    # 高级检查（需要案例数据）
    if case_events is not None:
        last_event = case_events.iloc[-1]
        if activity == last_event['activity'] and last_event.get('is_goal', False):
            return True
            
    return False

def get_resource_utilization(activity, event_log):
    """计算活动资源利用率（基于历史资源分配数据）"""
    # 1. 获取该活动涉及的所有资源
    resources = set()
    activity_records = event_log[event_log['activity'] == activity]
    if not activity_records.empty:
        resources = set(activity_records['resource'].unique())
    
    # 2. 计算资源平均利用率
    total_utilization = 0
    valid_resources = 0
    
    for resource in resources:
        # 获取该资源的总工作时间和空闲时间
        resource_logs = event_log[event_log['resource'] == resource]
        if len(resource_logs) > 0:
            working_time = sum(
                (row['end_time'] - row['start_time']).total_seconds()
                for _, row in resource_logs.iterrows()
            )
            total_time = (resource_logs['end_time'].max() - 
                         resource_logs['start_time'].min()).total_seconds()
            
            if total_time > 0:
                utilization = working_time / total_time
                total_utilization += min(utilization, 1.0)  # 不超过100%
                valid_resources += 1
    
    # 返回平均利用率（0-1范围），默认0.5表示中等利用率
    return total_utilization / valid_resources if valid_resources > 0 else 0.5


def is_valid_transition(current_activity, next_activity):
    """检查从当前活动到下一活动的转移是否合规"""
    # 1. 硬编码的业务规则检查
    forbidden_transitions = {
        '申请提交': ['审批拒绝'],  # 提交后不能直接到拒绝
        '审批通过': ['材料补交']   # 通过后不应再补材料
    }
    if current_activity in forbidden_transitions:
        if next_activity in forbidden_transitions[current_activity]:
            return False

    # 2. 基于流程挖掘发现的合规路径
    valid_paths = {
        '申请提交': ['材料审核', '初审'],
        '材料审核': ['初审', '材料补交'],
        '初审': ['终审', '审批通过', '审批拒绝']
    }
    if current_activity in valid_paths:
        return next_activity in valid_paths[current_activity]
    
    # 3. 默认允许未知路径（可根据需求调整）
    return True

def get_activity_duration(activity, event_log):
    """计算活动平均持续时间（基于历史事件日志）"""
    # 从事件日志中获取该活动的所有持续时间记录
    durations = []
    for case in event_log:
        activities = case[case['activity'] == activity]
        if len(activities) > 1:
            start = activities.iloc[0]['timestamp']
            end = activities.iloc[-1]['timestamp']
            durations.append((end - start).total_seconds())
    
    # 返回平均持续时间（秒），至少有1小时默认值
    return np.mean(durations) if durations else 3600